
 #include <stdio.h>
 #include <malloc.h>
 #include <string.h>
 #include <dos.h>
 #include <process.h>

 struct tagBMPFILEHEADER{
	int bfType;
	long bfSize;
	int bfR1;
	int bfR2;
	long bfOffset;
	}bitmapfileheader;

 struct tagBITMAPINFOHEADER{
	long biSize;
	long biWidth;
	long biHeight;
	int biPlanes;
	int biBitCount;
	long biCompress;
	long biSizeImage;
	long biXPeIsPerMeter;
	long biYPeIsPerMeter;
	long biCIrUsed;
	long biCIrImprotant;
	}bitmapinfoheader;

 struct tagRGBQUAD{
	unsigned char rgbBlue;
	unsigned char rgbGreen;
	unsigned char rgbRed;
	unsigned char rgbReserved;
	}rgbquad;


void set_palette(FILE *fp)
	{
	unsigned char i,j;

	fseek(fp,0x36,SEEK_SET);
	for(i=0;i<16;i++){
		outportb(0x3c8,i);
		fread((char*)&rgbquad,sizeof(rgbquad),1,fp);
		outportb(0x3c9,rgbquad.rgbRed>>2);
		outportb(0x3c9,rgbquad.rgbGreen>>2);
		outportb(0x3c9,rgbquad.rgbBlue>>2);
		}
	for( i=0;i<16;i++)
		asm{ mov ah,16; mov al,0; mov bl,i; mov bh,bl; int 16 }
	}

void display_bmp(FILE *fp,int col,int row)
	{
	 unsigned long height,width,linebytes;
	 unsigned char color;
	 char *linebuf;

	 linebuf=(char*)malloc(640);
	 fseek(fp,bitmapfileheader.bfOffset,SEEK_SET);
	 height=bitmapinfoheader.biHeight;
	 width=bitmapinfoheader.biWidth;
	 linebytes=((width/2+3)/4)*4;
	 for(int i=0;i<height;i++){
		fread(linebuf,1,linebytes,fp);
		for(int j=0;j<width-1;j++){
			color=linebuf[j/2];
			asm{ mov ah,12; mov cx,col; add cx,j; mov dx,row
				 sub dx,i; mov al,color; and al,240; shr al,1
				 mov bx,0; shr al,1; shr al,1; shr al,1; inc j
				 int 16
				  }
			asm{ mov ah,12; mov cx,col; add cx,j; mov dx,row
				 mov bx,0; sub dx,i; mov al,color; and al,15
				 int 16
				 }
			//putpixel(col+j++,row-i,(color&0x0f0)>>4);
			//putpixel(col+j,row-i,color&0x0f);
			}
		}
	free(linebuf);
	fclose(fp);
	}


void main(int argc,char** argv)
	{
	FILE *fp;
	if(argc==1){
		printf("Usage:%s imagfile\n",strupr(argv[0]) );
		exit(1);
		}

	if((fp=fopen(argv[1],"rb"))==NULL){
		printf("[%s]open error.\n",argv[1]);
		exit(1);
		}

	if(fread((char *)&bitmapfileheader,1,sizeof(bitmapfileheader),fp)
		!=sizeof(bitmapfileheader)){
		printf("[%s] read error.\n",argv[1]);
		exit(1);
		}

	if(fread((char *)&bitmapinfoheader,1,sizeof(bitmapinfoheader),fp)
		!=sizeof(bitmapinfoheader)){
		printf("[%s] read error.\n",argv[1]);
		exit(1);
		}

	if(bitmapinfoheader.biCompress!=0){
		printf("Only supports non_compressed BMP file!\n");
		exit(1);
		}
	if(bitmapinfoheader.biBitCount!=1&&bitmapinfoheader.biBitCount!=4
		&&bitmapinfoheader.biBitCount!=8){
		printf("[%s] is not a BMP file!\n",argv[1]);
		exit(1);
		}

	//int graphdrv=DETECT;
	//int graphmode;
	//registerfarbgidriver(EGAVGA_driver_far);
	//initgraph(&graphdrv,&graphmode,"");
	asm{ mov ah,0; mov al,18; int 16 }

	//outportb(0x3c4,1);
	//outportb(0x3c5,33);

	set_palette(fp);
	display_bmp(fp,10,470);

	outportb(0x3c4,1);
	outportb(0x3c5,1);

	delay(2000);
	//closegraph();
	//restorecrtmode();
	asm{ mov ah,0; mov al,3; int 16 }
	}
